/*
 * Copyright (c) 2024 iSoftStone Education Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include "los_task.h"
#include "ohos_init.h"
#include "sht30.h"
#include "iot_errno.h"
#include "iot_gpio.h"
#include "picture.h"
#include "lcd.h"


float g_humi;
float g_temp;

/* GPIO定义 */
#define GPIO_BODY_INDUCTION      GPIO0_PA3  // 人体感应传感器
#define GPIO_LED                 GPIO0_PA5  // LED灯

/* 全局变量 */
static volatile uint8_t g_human_detected = 0;  // 人体检测标志
static volatile uint8_t g_led_state = 0;       // LED状态
static unsigned int g_no_detection_count = 0;  // 无人体检测计数

/***************************************************************
* 函数名称: gpio_isr_func
* 说    明: 人体感应中断处理函数
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void gpio_isr_func(void *args)
{
    printf("Human detected!\n");
    g_human_detected = 1;          // 设置人体检测标志
    g_no_detection_count = 0;      // 重置无人体计数
    
    // 立即点亮LED
    IoTGpioSetOutputVal(GPIO_LED, IOT_GPIO_VALUE1);
    g_led_state = 1;
}

/***************************************************************
* 函数名称: led_control_task
* 说    明: LED控制任务
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void led_control_task()
{
    // 初始化LED GPIO
    IoTGpioInit(GPIO_LED);
    IoTGpioSetDir(GPIO_LED, IOT_GPIO_DIR_OUT);

    
    while (1) {
        if (g_human_detected) {
            // 人体检测模式下，LED保持常亮
            if (!g_led_state) {
                IoTGpioSetOutputVal(GPIO_LED, IOT_GPIO_VALUE1);
                g_led_state = 1;
            }
            
            // 检查是否连续10秒无人体活动
            if (g_no_detection_count >= 10) {
                g_human_detected = 0;
                g_no_detection_count = 0;
                printf("No human detected for 10s, return to blinking mode\n");
            }
        } else {
            // 正常模式下，LED0.5秒闪烁
            g_led_state = !g_led_state;
            IoTGpioSetOutputVal(GPIO_LED, g_led_state);
        }
        
        LOS_Msleep(500);  // 500ms控制周期
    }
}

/***************************************************************
* 函数名称: human_check_task
* 说    明: 人体检测状态维护任务
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void human_check_task()
{
    // 初始化人体感应传感器GPIO
    IoTGpioInit(GPIO_BODY_INDUCTION);
    IoTGpioSetDir(GPIO_BODY_INDUCTION, IOT_GPIO_DIR_IN);
    
    // 设置中断(上升沿触发)
    int ret = IoTGpioRegisterIsrFunc(GPIO_BODY_INDUCTION, 
                    IOT_INT_TYPE_EDGE, 
                    IOT_GPIO_EDGE_RISE_LEVEL_HIGH, 
                    gpio_isr_func, NULL);
    if (ret != IOT_SUCCESS) {
        printf("Failed to register ISR: %d\n", ret);
        return;
    }
    IoTGpioSetIsrMask(GPIO_BODY_INDUCTION, FALSE);  // 启用中断
    
    while (1) {
        printf("Human detection status: %s\n", 
              g_human_detected ? "Detected" : "Not detected");
        
        // 如果当前是检测状态，每秒增加无检测计数
        if (g_human_detected) {
            g_no_detection_count++;
        }
        
        LOS_Msleep(1000);  // 每秒检查一次
    }
}


/***************************************************************
 * 函数名称: sht30_proress
 * 说    明: sht30实验
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
void sht30_proress(void *arg)
{
    double sht30_data[2] = {0};

    /* 初始化sht30 */
    sht30_init();

    while (1)
    {
        printf("************ Sht30 Process ************\n");

        /* 读取sht30数据 */
        sht30_read_data(sht30_data);

        printf("temperature %.2f RH %.2f \r\n", sht30_data[0], sht30_data[1]);

        g_temp = sht30_data[0];
        g_humi = sht30_data[1];

        printf("\r\n");

        LOS_Msleep(1000);
    }
}

/***************************************************************
 * 函数名称: sht30_example
 * 说    明: 开机自启动调用函数
 * 参    数: 无
 * 返 回 值: 无
 ***************************************************************/
void sht30_example()
{
   unsigned int thread_id, led_task_id, human_task_id;
    TSK_INIT_PARAM_S task = {0}, led_task = {0}, human_task = {0};
    unsigned int ret = LOS_OK;

    // 1. 创建SHT30温湿度检测任务（原任务）
    task.pfnTaskEntry = (TSK_ENTRY_FUNC)sht30_proress;
    task.uwStackSize = 2048;
    task.pcName = "sht30 process";
    task.usTaskPrio = 23;  // 调整优先级为23（原24）
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK) {
        printf("Failed to create SHT30 task:0x%x\n", ret);
    }

    // 2. 创建LED控制任务（新增）
    led_task.pfnTaskEntry = (TSK_ENTRY_FUNC)led_control_task;
    led_task.uwStackSize = 2048;
    led_task.pcName = "LED Control Task";
    led_task.usTaskPrio = 25;  // 最高优先级
    ret = LOS_TaskCreate(&led_task_id, &led_task);
    if (ret != LOS_OK) {
        printf("Failed to create LED task: 0x%x\n", ret);
    }
    
    // 3. 创建人体检测任务（新增）
    human_task.pfnTaskEntry = (TSK_ENTRY_FUNC)human_check_task;
    human_task.uwStackSize = 2048;
    human_task.pcName = "Human Detect Task";
    human_task.usTaskPrio = 24;  // 中优先级
    ret = LOS_TaskCreate(&human_task_id, &human_task);
    if (ret != LOS_OK) {
        printf("Failed to create human detect task: 0x%x\n", ret);
    }
}

APP_FEATURE_INIT(sht30_example);
